/********************************** (C) COPYRIGHT *******************************
 * File Name          : main.c
 * Author             : WCH
 * Version            : V1.0.0
 * Date               : 2021/06/06
 * Description        : Main program body.
 * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
 * SPDX-License-Identifier: Apache-2.0
 *******************************************************************************/

#include "IAP.h"
#include "ch32v30x_usbhs_device.h"

extern void USBHS_IRQHandler(void);

void Flash_Write_Word(uint32_t *buffer, uint32_t addr, uint16_t Len);
void USB_Send_Report(uint8_t *buff, uint16_t len)
{
    // while (USBHS_Endp1_Up_Flag != RESET);
    Ep1_Tx(buff, len);
}
uint8_t report[9] = {0x01, 0, 0, 0, 0, 0, 0, 0, 1};
uint32_t buffer[64];
volatile uint8_t down_flag = 0;

void SystemUpdate(UPDATA *updata)
{
    down_flag = 0;
    // printf("addr: %d , len : %d , data1 : %08x\n", updata->start_addr, updata->data_size, ((uint32_t *)updata->data)[0]);
    Flash_Write_Word((uint32_t *)updata->data, updata->start_addr, updata->data_size);
    // printf("%08x %08x\n", *((uint32_t *)updata->start_addr), updata->start_addr);
    down_flag = 1;
}

/**
 * @brief FLASH写入
 *
 * @param buffer 待写入数据
 * @param addr 待写入地址
 * @param Len 待写入长度 （Word）
 */
void Flash_Write_Word(uint32_t *buffer, uint32_t addr, uint16_t Len)
{
    FLASH_Unlock_Fast();
    FLASH_ErasePage_Fast(addr);
    FLASH_ProgramPage_Fast(addr, buffer);
}
/*********************************************************************
 * @fn      main
 *
 * @brief   Main program.
 *
 * @return  none
 */
int main(void)
{
    USART_Printf_Init(921600);
    if (read_flash_key() == FLASH_OPERATION_KEY_CODE_0)
    {
        NVIC_EnableIRQ(Software_IRQn);
        NVIC_SetPendingIRQ(Software_IRQn);
        while (1)
        {
            printf("Jump\n");
        }
    }
    else
    {
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
        Delay_Init();
        USART_Printf_Init(921600);
        USBHS_RCC_Init();
        USBHS_Device_Init(ENABLE);
        NVIC_EnableIRQ(USBHS_IRQn);
        SetVTFIRQ((u32)USBHS_IRQHandler, USBHS_IRQn, 0, ENABLE);
        printf("bootloader...\n");
        report[0] = 0x01;
        while (1)
        {
            if (down_flag)
            {
                report[8] = 0x00;
                USB_Send_Report(report, 9);
            }
            else
            {
                report[8] = 0x01;
                USB_Send_Report(report, 9);
            }
            Delay_Us(100);
        }
    }
}

void SW_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void SW_Handler(void)
{
    printf("JumpToApp\n");
    __asm("li  a6, 0x10000");
    __asm("jr  a6");
    while (1)
        ;
}